#include <vector>
#include <thread>
#include <queue>
#include <functional>
#include <condition_variable>
#include <atomic>
#include <mutex>

namespace comm {

class ThreadPool {
public:
    explicit ThreadPool(size_t threadCount);
    ~ThreadPool();

    // 提交任务到线程池
    template <typename F, typename... Args>
    void enqueue(F&& f, Args&&... args);

private:
    // 工作线程池
    std::vector<std::thread> workers;
    // 任务队列
    std::queue<std::function<void()>> tasks;
    // 用于保护任务队列的互斥锁
    std::mutex queueMutex;
    // 用于通知工作线程新的任务
    std::condition_variable condition;
    // 线程池是否运行
    std::atomic<bool> stop;

    // 工作线程
    void worker();
};

// 构造函数，创建指定数量的工作线程
ThreadPool::ThreadPool(size_t threadCount) : stop(false) {
    for (size_t i = 0; i < threadCount; ++i) {
        workers.emplace_back([this] { this->worker(); });
    }
}

// 析构函数，停止所有线程并清理资源
ThreadPool::~ThreadPool() {
    {
        std::unique_lock<std::mutex> lock(queueMutex);
        stop = true;
    }
    condition.notify_all();
    for (std::thread &worker : workers) {
        worker.join();
    }
}

// 工作线程处理任务
void ThreadPool::worker() {
    while (true) {
        std::function<void()> task;
        {
            std::unique_lock<std::mutex> lock(queueMutex);
            condition.wait(lock, [this] { return stop || !tasks.empty(); });

            if (stop && tasks.empty()) {
                return;
            }

            task = std::move(tasks.front());
            tasks.pop();
        }

        task();
    }
}

// 提交任务到线程池
template <typename F, typename... Args>
void ThreadPool::enqueue(F&& f, Args&&... args) {
    {
        std::unique_lock<std::mutex> lock(queueMutex);
        tasks.emplace([f = std::forward<F>(f), args = std::make_tuple(std::forward<Args>(args)...)]() {
            // 将 args 解包并转发给 f
            std::apply(f, std::move(args));
        });
    }
    condition.notify_one();
}

} // namespace comm
